﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text;
using System.Windows.Forms;
using System.Transactions;
using System.Threading;

namespace UpdateApp
{
    /// <summary>
    /// 桌面应用更新程序
    /// 启动时，根据主程序本地的版本文件（LocalVersion.xml），拿到远程更新地址，比较远程配置的版本文件（ServerVersion.xml）
    /// 如果有新版本，则判断更新程序是否位于系统盘，且是否为管理员身份运行
    /// 如果位于系统盘，且不是管理员身份运行，则重新以管理员身份运行更新重启，操作系统会弹出账号控制提示给客户
    /// 如果不是则打开主窗体，提示有新版本可以更新，是否下载更新
    /// （这个机制可以达到无论客户把程序装在系统盘还是其他盘都不会影响更新操作，并且如果客户不是装在系统盘，还可以免去每次检查更新系统都弹出"权限控制"的提示给客户）
    /// 下载更新完成后，会自动删除下载的更新包，并且重新启动主程序
    /// 
    /// 在主程序启动时，同时启动更新程序，即可检查更新了，如果客户选中暂时不更新，下次打开还是会提示更新，如果想跳过改版本，那就得在取消的时候做点操作
    /// 把远程最新版本号，修改到主程序本地的版本文件（LocalVersion.xml）
    /// LCJ 2019年1月4日12:25:37
    /// update 2019年12月19日12:32:35
    /// 框架修改为2.0
    /// 增加更新时 停、启指定windows服务功能
    /// </summary>
    public partial class Form1 : Form
    {
        public Form1(Param param)
        {
            List<string> list = new List<string> { "zh-CN", "zh-HK" };
            if (!list.Contains(Thread.CurrentThread.CurrentCulture.CompareInfo.Name))
            {
                Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("");
            }

            InitializeComponent();
            bool ifUpdate = param.RequiredUpdate;
            if (!ifUpdate)
            {
                ifUpdate = MessageBox.Show(Properties.Resources.HasNewVersion, Properties.Resources.NewVersion, MessageBoxButtons.YesNo) == DialogResult.Yes;
            }
            if (ifUpdate)
            {
                Update update = new Update() { DownloadFileCompleted = DownloadFileCompleted, DownloadProgressChanged = DownloadProgressChanged };
                try
                {
                    update.Download(param);
                }
                catch
                {
                    MessageBox.Show(Properties.Resources.DownLoadFail, Properties.Resources.NewVersion, MessageBoxButtons.OK);
                    Environment.Exit(0);
                }
            }
            else
            {
                Environment.Exit(0);
            }
        }
        /// <summary>
        /// 更新包下载完成，开始更新操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void DownloadFileCompleted(object sender, object args)
        {
            var e = args as AsyncCompletedEventArgs;
            if (!e.Cancelled && e.UserState != null)
            {
                MessageBox.Show(Properties.Resources.DownLoadSuccess, Properties.Resources.NewVersion, MessageBoxButtons.OK);
                var IsCancellationRequested = false;
                //解压文件、复制文件、删除文件 做个假进度
                new Thread(() =>
                {
                    BeginInvoke(new Action<int>((i) =>
                    {
                        progressBar1.Minimum = 0;
                        progressBar1.Maximum = 100;
                        progressBar1.Value = 0;
                        label1.Text = "";
                    }), 0);

                    Random r = new Random();
                    while (!IsCancellationRequested)
                    {
                        if (progressBar1.Value >= 100)
                        {
                            BeginInvoke(new Action<int>((i) =>
                            {
                                progressBar1.Value = 0;
                            }), 0);
                        }
                        else
                        {
                            BeginInvoke(new Action<int>((i) =>
                            {
                                progressBar1.Value += 1;
                            }), 0);
                        }
                        System.Threading.Thread.Sleep(r.Next(10, 100));
                    }
                    BeginInvoke(new Action<int>((i) =>
                    {
                        progressBar1.Value = 100;
                    }), 0);
                }).Start();
                new Thread(() =>
                {
                    var packPath = string.Empty;
                    var unpackPath = string.Empty;
                    try
                    {
                        var temp = e.UserState as Param;

                        //杀掉所有需要关闭的进程
                        var killList = temp.KillList.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (var item in killList)
                        {
                            UpdateApp.Update.CloseProcess(item);
                        }

                        //杀掉所有需要关闭的服务
                        var killServiceList = temp.KillServiceList.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (var item in killServiceList)
                        {
                            //等待服务停止 等待100次
                            var times = 100;
                            while (times > 0
                            && UpdateApp.Update.ServiceExists(item)
                            && UpdateApp.Update.ServiceStatus(item) != System.ServiceProcess.ServiceControllerStatus.Stopped)
                            {
                                UpdateApp.Update.StopService(item);
                                times--;
                                Thread.Sleep(5000);
                            }
                        }


                        //获取主程序的所在路径，这里因为是在主程序的安装根目录里放了一个文件夹，文件夹里面放更新程序的结构..\App\App.exe   ..\App\UpdateApp\UpdateApp.exe
                        var appPath = Directory.GetParent(Application.StartupPath).FullName;
                        //下载到的更新包的所在路径，与更新程序所在位置相同
                        packPath = Application.StartupPath + "\\" + temp.PackName.ToString() + ".zip";
                        //更新包解压路径，与更新程序所在位置相同
                        unpackPath = Application.StartupPath + "\\" + temp.PackName;
                        //开始解压
                        myZip.ZipHelper.UnZip(packPath, Application.StartupPath);
                        //复制新文件到主程序安装目录，至于文件复制失败之类的情况，没有处理，重新安装客户端吧
                        myZip.ZipHelper.CopyDirectory(unpackPath, appPath);

                        //操作完成，删除更新包
                        File.Delete(packPath);
                        //删除解压后的更新包
                        myZip.ZipHelper.DeleteFolder(unpackPath);
                        Directory.Delete(unpackPath, true);
                        //停止进度条
                        IsCancellationRequested = true;

                        MessageBox.Show(Properties.Resources.UpdateSuccess, Properties.Resources.NewVersion, MessageBoxButtons.OK);

                        //更新完成，重新打开服务
                        var reStartServiceList = temp.ReStartServiceList.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (var item in reStartServiceList)
                        {
                            UpdateApp.Update.StartService(item);
                        }

                        //更新完成，重新打开应用程序
                        var reStartList = temp.ReStartList.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (var item in reStartList)
                        {
                            try
                            {
                                Process p = new Process();
                                p.StartInfo.FileName = string.Format(@"{0}\{1}.exe", appPath, item);
                                p.Start();
                                p.Dispose();
                            }
                            catch { }
                        }

                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        //操作完成，删除更新包
                        File.Delete(packPath);
                        //删除解压后的更新包
                        myZip.ZipHelper.DeleteFolder(unpackPath);
                        Directory.Delete(unpackPath, true);
                    }
                    //退出更新程序
                    Environment.Exit(0);
                }).Start();
            }
            else
            {
                MessageBox.Show(Properties.Resources.DownLoadFail, Properties.Resources.NewVersion, MessageBoxButtons.OK);
                Environment.Exit(0);
            }
        }

        /// <summary>
        /// 更新下载进度条
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void DownloadProgressChanged(object sender, object args)
        {
            var e = args as DownloadProgressChangedEventArgs;
            progressBar1.Minimum = 0;
            progressBar1.Maximum = (int)e.TotalBytesToReceive;
            progressBar1.Value = (int)e.BytesReceived;
            label1.Text = e.ProgressPercentage + "%";
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}
